package ch5;

import util.Debug;
import util.Tools;

import java.util.Random;

/**
 * 告警代理
 */

public class AlarmAgent {
    // 保存该类的唯一实例
    private final static AlarmAgent INSTANCE = new AlarmAgent();
    // 是否连接上告警服务器的flag
    private boolean connectedToServer = false;
    // 心跳线程，检测告警代理和告警服务器的网络连接是否正常
    private final HeartbeartThread heartbeatThread = new HeartbeartThread();

    private AlarmAgent() {}

    public static AlarmAgent getInstance() {
        return INSTANCE;
    }

    public void init() {
        connectToServer();
        heartbeatThread.setDaemon(true);
        heartbeatThread.start();
    }

    private void connectToServer() {
        // 创建并启动网络连接线程，在该线程中与告警服务器建立连接
        new Thread() {
            @Override
            public void run() {
               doConnect();
            }
        }.start();
    }

    private void doConnect() {
        // 模拟实际操作耗时
        Tools.randomPause(100);
        synchronized (this) {
            connectedToServer = true;
            // 网络连接建立完毕，唤醒告警线程，使其向告警服务器发送告警信息
            notify();
        }
    }

    public void sentAlarm(String message) throws InterruptedException {
        synchronized (this) {
            // 如果网络连接尚未建立，则使当前线程等待
            while (!connectedToServer) {
                Debug.info("Alarm agent was not connected to server.");
                wait();
            }
            // 真正将告警信息上传到告警服务器
            doSendAlarm(message);
        }
    }

    private void doSendAlarm(String message) {
        // ... 实际操作
        Debug.info("Alarm sent: %s", message);
    }

    // 心跳线程
    class HeartbeartThread extends Thread {
        @Override
        public void run() {
           try {
               // 留出一定的时间给网络连接建立线程与告警服务器建立连接
               Thread.sleep(1000);
               while (true) {
                   if (checkConnection()) {
                       connectedToServer = true;
                   } else {
                       connectedToServer = false;
                       Debug.info("Alarm agent was disconnected from server.");
                       // 检测到连接中断，重新建立连接
                       connectToServer();
                   }
                   Thread.sleep(2000);
               }
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
        }

        // 检测与告警服务器的网络连接情况
        private boolean checkConnection() {
            boolean isConnected = true;
            final Random random = new Random();
            // 模拟随机的网络连接断开
            int rand = random.nextInt(1000);
            if (rand <= 500) {
                isConnected = false;
            }
            return isConnected;
        }
    }
}
